package com.zx.mobile.controller;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.zx.map.dao.model.MerchantInfo;
import com.zx.map.utils.CommonResponseUtils;
import com.zx.map.utils.MyBeanUtils;
import com.zx.map.utils.SUConstants;
import com.zx.mobile.domain.*;
import com.zx.mobile.domain.nocard.MobaoCheckSmsResponse;
import com.zx.mobile.domain.nocard.MobaoPrePayResponse;
import com.zx.mobile.utils.WebUtils;
import com.zx.platform.utils.HttpClientCommon;
import com.zx.platform.utils.StrUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.jd.jr.pay.gate.signature.util.BASE64;
import com.jd.jr.pay.gate.signature.util.RSACoder;
import com.jd.jr.pay.gate.signature.util.SHAUtil;
import com.jd.jr.pay.gate.signature.util.SignUtil;
import com.jd.jr.pay.gate.signature.util.ThreeDesUtil;
import com.yeepay.paymobile.utils.PaymobileUtils;
import com.zx.jd.model.TradeResultResponse;
import com.zx.jd.util.PropertyUtils;
import com.zx.map.service.HistoryPayCardInfoService;
import com.zx.map.service.OrdLogService;
import com.zx.map.service.domain.nocard.NocardCallBackDomain;
import com.zx.map.service.domain.nocard.NocardPayReturnDomain;
import com.zx.map.service.model.HistoryPayCardInfoModel;
import com.zx.map.service.model.OrdLogModel;
import com.zx.mobile.SessionHelper;
import com.zx.mobile.service.proxy.HistoryPayCardProxy;
import com.zx.mobile.service.proxy.JdNocardPayProxy;
import com.zx.mobile.service.proxy.NocardPayProxy;
import com.zx.platform.utils.PmpUtils;
import org.springframework.web.bind.annotation.ResponseBody;
import sun.misc.BASE64Decoder;

/**
 * Created by IntelliJ IDEA. User: Administrator Date: 15-7-5 Time: 下午8:09 To
 * change this template use File | Settings | File Templates.
 */
@Controller
@RequestMapping("/mobile/index")
public class MobileNocardController {
	/**
	 * log
	 */
	private static Logger log = Logger.getLogger(MobileNocardController.class);
	@Autowired
	private OrdLogService ordLogService;
	@Autowired
	private HistoryPayCardInfoService historyPayCardInfoService;


	/**
	 * 无卡收款
	 *
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping("/nocardincome")
	public String nocardincome(Model model, HttpServletRequest request,HttpServletResponse response) {
		try {
			// 获取session信息
			MobileUserDomain user = (MobileUserDomain) request.getSession()
					.getAttribute(SessionHelper.MOBILEUSER);
			HistoryPayCardInfoModel param = new HistoryPayCardInfoModel();
			param.setMerchantId(user.getMerchantInfoDetailModel()
					.getMerchantId());
			//List<HistoryPayCardInfoModel> list = historyPayCardInfoService
			//		.getListByModel(param);
			//list = HistoryPayCardProxy.transformHistoryPayCard(list);
			//request.getSession().setAttribute(SessionHelper.HISTORYPAYCARD,
			//		list);
			//model.addAttribute("list", list);
			response.setHeader("Pragma","No-cache");
			response.setHeader("Cache-Control","no-cache");
			response.setDateHeader("Expires", -10);
			return "jsp/mobile/nocard/nocardincome";
		} catch (Exception e) {
			model.addAttribute("errorMsg", "系统异常");
			log.error("系统异常", e);
			return "/jsp/mobile/error";
		}
	}

	/**
	 * 无卡收款 获取历史收款账号
	 *
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping("/historypaycard")
	public String historypaycard(
			HistoryPayCardInfoDomain historyPayCardInfoDomain, Model model,
			HttpServletRequest request) {
		try {
			// 获取session信息
			List<HistoryPayCardInfoModel> list = (List<HistoryPayCardInfoModel>) request
					.getSession().getAttribute(SessionHelper.HISTORYPAYCARD);
			list = HistoryPayCardProxy.transformHistoryPayCard(list);
			model.addAttribute("model", historyPayCardInfoDomain);
			model.addAttribute("list", list);
			return "/jsp/mobile/historypaycard";
		} catch (Exception e) {
			model.addAttribute("errorMsg", "系统异常");
			log.error("系统异常", e);
			return "/jsp/mobile/error";
		}
	}


	/**
	 * 无卡支付限额表
	 *
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping("/nocardlimit")
	public String nocardPayamtlimit(Model model, HttpServletRequest request) {
		try {
			return "jsp/mobile/nocard/nocardpayamtlimit";
		} catch (Exception e) {
			model.addAttribute("errorMsg", "系统异常");
			log.error("系统异常", e);
			return "/jsp/mobile/error";
		}
	}

	/**
	 * 无卡收款
	 *
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping("/nocarddealbycard")
	public String nocarddealbycard(NocardIncomeDomain nocardIncomeDomain,
	                               Model model, HttpServletRequest request) {
		try {
			// 获取session信息
			MobileUserDomain user = (MobileUserDomain) request.getSession()
					.getAttribute(SessionHelper.MOBILEUSER);
			HistoryPayCardInfoModel param = new HistoryPayCardInfoModel();
			param.setMerchantId(user.getMerchantInfoDetailModel()
					.getMerchantId());
			param.setBankAccount(nocardIncomeDomain.getIncomeCardNo());
			List<HistoryPayCardInfoModel> list = historyPayCardInfoService
					.getListByModel(param);
			for (HistoryPayCardInfoModel temp : list) {
				if (temp.getBankAccount().equals(
						nocardIncomeDomain.getIncomeCardNo())) {
					model.addAttribute("payCard", temp);
				}
			}
			model.addAttribute("model", nocardIncomeDomain);
			return "/jsp/mobile/noCardForPayType";
		} catch (Exception e) {
			model.addAttribute("errorMsg", "系统异常");
			log.error("系统异常", e);
			return "/jsp/mobile/error";
		}
	}

	/**
	 * 无卡收款结果
	 *
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping("/nocardPayResult")
	public String nocardPayResult(Model model, HttpServletRequest request) {
		try {
			return "jsp/mobile/nocard/nocardresult";
		} catch (Exception e) {
			model.addAttribute("errorMsg", "系统异常");
			log.error("系统异常", e);
			return "/jsp/mobile/error";
		}
	}

	/**
	 * 无卡收款
	 *
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping("/nocarddeal")
	public String nocarddeal(NocardIncomeDomain nocardIncomeDomain,
	                         Model model, HttpServletRequest request,
	                         HttpServletResponse response) throws IOException {
		try {
			log.info("无卡收款："
					+ ToStringBuilder.reflectionToString(nocardIncomeDomain));

			// 跳转到选择支付方式
			model.addAttribute("nocardIncomeDomain", nocardIncomeDomain);
			return "jsp/mobile/nocard/noCardPayType";
		} catch (Exception e) {
			log.error("系统异常", e);
			return "/jsp/mobile/error.jsp";
			// response.sendRedirect(request.getContextPath()+"/jsp/mobile/error.jsp");
		}
	}

	/**
	 * 无卡支付
	 *
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping("/noCardForPayType")
	public String noCardForPayType(NocardIncomeDomain nocardIncomeDomain,
	                               Model model, HttpServletRequest request,
	                               HttpServletResponse response) {
		try {
			MobileUserDomain user = WebUtils.queryCurrentLoginInfo(request);
			if ("mb".equals(nocardIncomeDomain.getPayType())) {// 摩宝支付  转入自定义界面

				HistoryPayCardInfoModel param = new HistoryPayCardInfoModel();
				param.setMerchantId(user.getMerchantInfoDetailModel()
						.getMerchantId());
				param.setBankAccount(nocardIncomeDomain.getIncomeCardNo());
				List<HistoryPayCardInfoModel> list = historyPayCardInfoService
						.getListByModel(param);
				HistoryPayCardInfoModel temp = new HistoryPayCardInfoModel();
				for (HistoryPayCardInfoModel temp1 : list) {
					if (temp1.getBankAccount().equals(
							nocardIncomeDomain.getIncomeCardNo())) {
						temp = temp1;
					}
				}
				temp.setLastCardNo(nocardIncomeDomain.getIncomeCardNo().substring(
						nocardIncomeDomain.getIncomeCardNo().length() - 4));
				model.addAttribute("payCard", temp);
				model.addAttribute("nocardIncomeDomain", nocardIncomeDomain);
				return "jsp/mobile/nocard/nocardincomeconfirm";
			}


			//测试时用到
			/*user = MobileControlHelper.reloadSessionInfoByMerchantId(
					merchantInfoService, "M1606", "1111", request);*/
			// 0、获取订单编号实名制信息
			NocardConfirmPayDomain payDomain = new NocardConfirmPayDomain();
			String orderId = PmpUtils.getNoCardOrderNum();
			payDomain.setAmount(nocardIncomeDomain.getIncomeAmt());
			payDomain.setCardNo(nocardIncomeDomain.getIncomeCardNo());
			payDomain.setPayType(nocardIncomeDomain.getPayType());
			payDomain.setOrderId(orderId);
			payDomain.setIdCard(user.getMerchantInfoDetailModel()
					.getLegalIdentityno());
			payDomain.setOwner(user.getMerchantInfoDetailModel()
					.getMerchantName());
			if ("yb".equals(payDomain.getPayType())) {// 易宝支付
				// 2、保存订单
				OrdLogModel ordLogModel = NocardPayProxy.transformToOrdLog(
						payDomain, user);
				BigDecimal amt = new BigDecimal(payDomain.getAmount());
				ordLogModel.setPaymentAmt(amt.doubleValue());
				ordLogModel.setOrdId(payDomain.getOrderId());
				ordLogModel.setPaymentType(payDomain.getPayType());
				ordLogService.add(ordLogModel);
				String payUrl = NocardPayProxy.getNoCardPayUrl(payDomain);
				// 3、跳转到支付链接payUrl
				// edit by wenjw 2016.9.30 国庆期间此功能被禁用
				response.sendRedirect(payUrl);
				return null;
				// 国庆后放开此功能
				// response.sendRedirect(request.getContextPath()+"/jsp/mobile/stopNotice.jsp");
			} else if ("jd".equals(payDomain.getPayType())) {// 京东支付
				// 2、保存订单
				OrdLogModel ordLogModel = NocardPayProxy.transformToOrdLog(
						payDomain, user);//易宝支付
				BigDecimal amt = new BigDecimal(payDomain.getAmount());
				ordLogModel.setPaymentAmt(amt.doubleValue());
				ordLogModel.setOrdId(payDomain.getOrderId());
				ordLogModel.setPaymentType(payDomain.getPayType());
				ordLogService.add(ordLogModel);
				String payUrl = JdNocardPayProxy.getNoCardPayUrl(payDomain,
						request, user.getMerchantInfoDetailModel());
				return payUrl;
			} else {
				model.addAttribute("errorMsg", "不支持此支付方式");
				return "/jsp/mobile/error";
			}

		} catch (Exception e) {
			model.addAttribute("errorMsg", "无卡支付异常");
			log.error("无卡支付异常", e);
			return "/jsp/mobile/error";
		}
	}


	/**
	 * 自定义支付信息界面
	 *
	 * @return
	 */
	@RequestMapping("/nocardConfirmPay")
	@ResponseBody
	public Map nocardConfirmPay(NocardCommonPayDomain nocardCommonPayDomain,
	                            Model model, HttpServletRequest request) {

		try {
			String cardType=nocardCommonPayDomain.getCardType();
			if("00".equals(cardType)){//信用卡
				String cvv2=nocardCommonPayDomain.getCvv2();
				String expireDate=nocardCommonPayDomain.getExpireDate();
				if(StrUtils.isBlank(cvv2)||cvv2.length()!=3){
					return CommonResponseUtils.failureResponse("未填写信用卡背面后三位数或格式不正确");
				}
				if(StrUtils.isBlank(expireDate)||expireDate.length()!=4){
					return CommonResponseUtils.failureResponse("未填写有效期或格式不正确");
				}
			}
			String orderId = PmpUtils.getNoCardOrderNum();
			String preUrl = NocardPayProxy.getMobaoPrePayUrl(nocardCommonPayDomain, orderId);
			MobaoPrePayResponse mobaoPrePayResponse = new HttpClientCommon().getResult(MobaoPrePayResponse.class, preUrl);
			log.debug("摩宝预支付返回：" + MyBeanUtils.beanToJson(mobaoPrePayResponse));
			if (mobaoPrePayResponse.getStatus().equals("00") && mobaoPrePayResponse.getRefCode().equals("01")) {//预支付成功
				//保存订单
				MobileUserDomain user = WebUtils.queryCurrentLoginInfo(request);
				nocardCommonPayDomain.setCardType("00".equals(nocardCommonPayDomain.getCardType())?"C":"D");
				OrdLogModel ordLogModel = NocardPayProxy.transformToOrdLog(nocardCommonPayDomain, user);//易宝支付
				ordLogModel.setOrdId(orderId);
				ordLogService.add(ordLogModel);
				 return CommonResponseUtils.successResponse("短信已发送到手机",mobaoPrePayResponse);
			} else {
				log.error("无卡摩宝 摩宝端支付异常");
				return CommonResponseUtils.failureResponse(mobaoPrePayResponse.getRefMsg());
			}
		} catch (Exception e) {
			log.error("无卡摩宝 支付异常", e);
			return CommonResponseUtils.failureResponse(SUConstants.SERVER_ERROR);
		}
	}

	/**
	 * 摩宝校验短信验证码
	 *
	 * @return
	 */
	@RequestMapping("/mobaoCheckSms")
	public String mobaoCheckSms(MobaoPrePayResponse mobaoPrePayResponse,
	                            Model model, HttpServletRequest request) {

		try {
			//验证验证码
			String checkUrl = NocardPayProxy.getMobaoCheckSmsUrl(mobaoPrePayResponse);
			MobaoCheckSmsResponse mobaoCheckSmsResponse = new HttpClientCommon().getResult(MobaoCheckSmsResponse.class, checkUrl);

			log.debug("摩宝短信校验返回：" + MyBeanUtils.beanToJson(mobaoCheckSmsResponse));

			OrdLogModel ordLogModel=ordLogService.getModelByKey(mobaoCheckSmsResponse.getOrderId());

			NocardPayReturnDomain nocardPayReturnDomain = new NocardPayReturnDomain();
			nocardPayReturnDomain.setOrderId(mobaoPrePayResponse.getOrderId());
			nocardPayReturnDomain.setYbOrderId(mobaoCheckSmsResponse.getKsPayOrderId());
			nocardPayReturnDomain.setAmount(""+ordLogModel.getPaymentAmt());
			String cardNo=ordLogModel.getBankAccount();
			String cardNo4Last=cardNo.substring(cardNo.length()-4);
			nocardPayReturnDomain.setLastNo(cardNo4Last);

			//摩宝支付
			nocardPayReturnDomain.setPaymentType("mb");
			if(mobaoCheckSmsResponse.getStatus().equals("00")) {
				if(mobaoCheckSmsResponse.getRefCode().equals("00")) {
					nocardPayReturnDomain.setStatus("S");
				} else if(mobaoCheckSmsResponse.getRefCode().equals("02")) {
					nocardPayReturnDomain.setStatus("F");
					model.addAttribute("errorMsg", mobaoCheckSmsResponse.getRefMsg());
				}
			} else {
				nocardPayReturnDomain.setStatus("F");
				model.addAttribute("errorMsg", mobaoCheckSmsResponse.getRefMsg());
			}
			//后台通知结果
		    try {
				new HttpClientCommon().getResultByGet(NocardPayProxy.getOrderNotifyPayUrl(nocardPayReturnDomain,ordLogModel));
		    }catch (Exception e){
				log.debug("摩宝支付回调通知异常:",e);
		    }

			model.addAttribute("model", nocardPayReturnDomain);
			return "jsp/mobile/nocard/nocardresult";

		} catch (Exception e) {
			model.addAttribute("errorMsg", "服务器异常");
			log.error("无卡摩宝 支付异常", e);
			return "/jsp/mobile/error";
		}
	}

	/**
	 * 无卡收款
	 *
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping("/nocardFrontCallBack")
	public String nocardFrontCallBack(
			NocardCallBackDomain nocardCallBackDomain, Model model,
			HttpServletRequest request, HttpServletResponse response) {
		try {
			// 解密data
			log.info("返回的参数："
					+ ToStringBuilder.reflectionToString(nocardCallBackDomain));
			TreeMap<String, String> dataMap = PaymobileUtils.decrypt(
					nocardCallBackDomain.getData(),
					nocardCallBackDomain.getEncryptkey());
			log.info("返回的明文参数：" + dataMap);
			// sign验签
			if (!PaymobileUtils.checkSign(dataMap)) {
				log.error("无卡支付返回验签失败");
				model.addAttribute("errorMsg", "系统异常");
				return "/jsp/mobile/error";
			}
			// {amount=1, bank=招商银行, bankcode=CMBCHINA, cardtype=2, lastno=6187,
			// merchantaccount=10012429710,
			// orderid=N201608041459780, status=1, yborderid=411608045221375101}
			String amount = new BigDecimal(dataMap.get("amount")).divide(
					new BigDecimal("100")).toString();
			NocardPayReturnDomain nocardPayReturnDomain = new NocardPayReturnDomain();
			nocardPayReturnDomain.setOrderId(dataMap.get("orderid"));
			nocardPayReturnDomain.setAmount(amount);
			nocardPayReturnDomain.setLastNo(dataMap.get("lastno"));
			nocardPayReturnDomain.setStatus("1".equals(dataMap.get("status")) ? "S" : "F");
			//易宝支付
			nocardPayReturnDomain.setPaymentType("yb");
			model.addAttribute("model", nocardPayReturnDomain);
			return "jsp/mobile/nocard/nocardresult";
		} catch (Exception e) {
			model.addAttribute("errorMsg", "系统异常");
			log.error("系统异常", e);
			return "/jsp/mobile/error";
		}
	}

	/**
	 * 京东无卡收款
	 *
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping("/jdNocardFrontCallBack")
	public String jdNocardFrontCallBack(
			NocardCallBackDomain nocardCallBackDomain, Model model,
			HttpServletRequest request, HttpServletResponse response) {
		try {

			System.out.println("接收页面回调成功请求开始" + "-----------------");
			TradeResultResponse tradeResultRes = new TradeResultResponse();
			String desKey = PropertyUtils.getProperty("wepay.merchant.desKey");

			byte[] key = BASE64.decode(desKey);

			String tradeNum = request.getParameter("tradeNum");
			tradeResultRes.setTradeNum(ThreeDesUtil.decrypt4HexStr(key, tradeNum));

			String tradeAmount = request.getParameter("amount");
			tradeResultRes.setAmount(ThreeDesUtil.decrypt4HexStr(key, tradeAmount));

			String tradeCurrency = request.getParameter("currency");
			tradeResultRes.setCurrency(ThreeDesUtil.decrypt4HexStr(key, tradeCurrency));

			String tradeDate = request.getParameter("tradeTime");
			tradeResultRes.setTradeTime(ThreeDesUtil.decrypt4HexStr(key, tradeDate));

			String tradeNote = request.getParameter("note");
			tradeResultRes.setNote(ThreeDesUtil.decrypt4HexStr(key, tradeNote));

			String tradeStatus = request.getParameter("status");
			tradeResultRes.setStatus(ThreeDesUtil.decrypt4HexStr(key, tradeStatus));

			String sign = request.getParameter("sign");
			System.out.println("sign:" + sign);

			String strSourceData = SignUtil.signString(tradeResultRes, new ArrayList<String>());
			System.out.println("strSourceData:" + strSourceData);
			byte[] decryptBASE64Arr = new BASE64Decoder().decodeBuffer(sign);
			String wyPubKey = PropertyUtils.getProperty("wepay.jd.rsaPublicKey");

			byte[] decryptArr = RSACoder.decryptByPublicKey(decryptBASE64Arr, wyPubKey);
			String decryptStr = new String(decryptArr, "UTF-8");
			System.out.println("decryptStr:" + decryptStr);

			String sha256SourceSignString = SHAUtil.Encrypt(strSourceData, null);
			System.out.println("sha256SourceSignString:" + sha256SourceSignString);
			System.out.println(decryptStr + "|" + sha256SourceSignString);

			if (!decryptStr.equals(sha256SourceSignString)) {

				request.setAttribute("errorMsg", "验证签名失败！");
				return "/jsp/mobile/error";
			} else {
				System.out.println("接收页面回调成功------" + tradeResultRes);
				request.setAttribute("tradeResultRes", tradeResultRes);
				String amount = new BigDecimal(tradeResultRes.getAmount()).divide(
						new BigDecimal("100")).toString();
				NocardPayReturnDomain nocardPayReturnDomain = new NocardPayReturnDomain();
				nocardPayReturnDomain.setOrderId(tradeResultRes.getTradeNum());
				nocardPayReturnDomain.setAmount(amount);
				nocardPayReturnDomain.setLastNo("");
				//0表示成功
				nocardPayReturnDomain
						.setStatus("0".equals(tradeResultRes.getStatus()) ? "S" : "F");
				//京东支付
				nocardPayReturnDomain.setPaymentType("jd");
				model.addAttribute("model", nocardPayReturnDomain);
				return "jsp/mobile/nocard/nocardresult";
			}
		} catch (Exception e) {
			model.addAttribute("errorMsg", "系统异常");
			log.error("系统异常", e);
			return "/jsp/mobile/error";
		}
	}
}
